package com.young.lib_fragments.acs

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener
import androidx.fragment.app.FragmentTransaction
import com.young.lib_fragments.anim.DefaultFmTransactionAnim
import com.young.lib_fragments.anim.IFmTransactionAnim
import com.young.lib_fragments.fms.BaseLazyFragment
import com.young.lib_fragments.fms.interfaces.IGetFragmentContainerId
import com.young.lib_fragments.fms.interfaces.ITransitions
import com.young.lib_fragments.utils.DispatchOnWindowFocusUtil
import com.young.lib_fragments.utils.FmTransitionsUtil
import com.young.lib_fragments.utils.HandleExceptionBackStackUtil
import com.young.lib_fragments.utils.RegisterForActivityResultUtil

/**
 * @author huangzehui
 * @date 2025/1/10 13:04 周五
 * @description 基础的 activity
 */
abstract class BaseActivity : FragmentActivity(), IGetFragmentContainerId, ITransitions {

    /**
     * startActivityForResult 的替代方式辅助类
     */
    protected val registerForActivityResultUtil by lazy {
        RegisterForActivityResultUtil(lifecycle)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerOnBackStackChangedListener()
    }

    override fun onDestroy() {
        super.onDestroy()
        unRegisterOnBackStackChangedListener()
        HandleExceptionBackStackUtil.clearAllBackTask()
    }

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        DispatchOnWindowFocusUtil.disPathOnWindowFocusChanged(supportFragmentManager, hasFocus)
    }

    // 栈的处理相关 start

    // 栈的监听变化
    private var mOnBackStackChangedListener: FragmentManager.OnBackStackChangedListener? = null


    /**
     * 注册栈的监听变化
     */
    private fun registerOnBackStackChangedListener() {
        mOnBackStackChangedListener = OnBackStackChangedListener {
            supportFragmentManager.removeOnBackStackChangedListener(mOnBackStackChangedListener!!)
            HandleExceptionBackStackUtil.handleExceptionBackStack(supportFragmentManager)
            supportFragmentManager.addOnBackStackChangedListener(mOnBackStackChangedListener!!)
        }
        supportFragmentManager.addOnBackStackChangedListener(mOnBackStackChangedListener!!)
    }

    /**
     * 注销栈的监听变化
     */
    private fun unRegisterOnBackStackChangedListener() {
        mOnBackStackChangedListener?.let {
            supportFragmentManager.removeOnBackStackChangedListener(it)
            mOnBackStackChangedListener = null
        }
    }

    // 栈的处理相关 end


    // fragment 操作 start

    override fun start(
        fm: Fragment,
        args: Bundle?,
        isToBackStack: Boolean,
        toBackStackName: String?,
        fmTag: String?,
        fmTransactionAnim: IFmTransactionAnim?
    ) {
        args?.let {
            fm.arguments = it
        }

        FmTransitionsUtil.addFm(
            fmManager = supportFragmentManager,
            containerViewId = getFragmentContainerId(),
            fm = fm,
            fmTag = fmTag,
            isToBackStack = isToBackStack,
            toBackStackName = toBackStackName,
            fmTransactionAnim = fmTransactionAnim ?: getDefaultFmTransactionAnim()
        )
    }


    override fun start(
        fmTransaction: FragmentTransaction,
        fm: Fragment,
        args: Bundle?,
        fmTag: String?,
        isToBackStack: Boolean,
        toBackStackName: String?,
        fmTransactionAnim: IFmTransactionAnim?
    ) {
        args?.let {
            fm.arguments = it
        }

        FmTransitionsUtil.addFm(
            fmManager = supportFragmentManager,
            fmTransaction = fmTransaction,
            containerViewId = getFragmentContainerId(),
            fm = fm,
            fmTag = fmTag,
            isToBackStack = isToBackStack,
            toBackStackName = toBackStackName,
            fmTransactionAnim = fmTransactionAnim ?: getDefaultFmTransactionAnim()
        )
    }

    override fun startWithPopFm(
        fm: Fragment,
        args: Bundle?,
        lastFm: Fragment,
        fmTag: String?,
        isToBackStack: Boolean,
        toBackStackName: String?,
        fmTransactionAnim: IFmTransactionAnim?,
        showCompletedTime: Long
    ) {
        args?.let {
            fm.arguments = it
        }

        FmTransitionsUtil.addWithPopFm(
            fmManager = supportFragmentManager,
            containerViewId = getFragmentContainerId(),
            fm = fm,
            lastFm = lastFm,
            fmTag = fmTag,
            isToBackStack = isToBackStack,
            toBackStackName = toBackStackName,
            fmTransactionAnim = fmTransactionAnim ?: getDefaultFmTransactionAnim(),
            showCompletedTime = showCompletedTime
        )
    }

    override fun pop() {
        FmTransitionsUtil.pop(supportFragmentManager)
    }

    override fun pop2Root() {
        FmTransitionsUtil.pop2Root(supportFragmentManager)
    }

    override fun pop2BackStackNameFm(toBackStackName: String, isInclude: Boolean) {
        FmTransitionsUtil.pop2BackStackNameFm(supportFragmentManager, toBackStackName, isInclude)
    }

    override fun pop2IdFm(id: Int, isInclude: Boolean) {
        FmTransitionsUtil.pop2IdFm(supportFragmentManager, id, isInclude)
    }

    override fun pop2TargetFmCls(fragmentCls: Class<out Fragment>, isInclude: Boolean) {
        FmTransitionsUtil.pop2TargetFmCls(supportFragmentManager, fragmentCls, isInclude)
    }

    override fun removeFragment(fm: Fragment?) {
        FmTransitionsUtil.removeFragment(supportFragmentManager, fm)
    }

    override fun show(
        fm: Fragment,
        args: Bundle?,
        fmTag: String?,
        fmTransactionAnim: IFmTransactionAnim?
    ) {
        FmTransitionsUtil.show(
            fmManager = supportFragmentManager,
            containerViewId = getFragmentContainerId(),
            fm = fm,
            fmTag = fmTag,
            fmTransactionAnim = fmTransactionAnim ?: getDefaultFmTransactionAnim()
        )
    }

    override fun hide(fm: Fragment, fmTransactionAnim: IFmTransactionAnim?) {
        FmTransitionsUtil.hide(
            supportFragmentManager,
            fm,
            fmTransactionAnim ?: getDefaultFmTransactionAnim()
        )
    }

    override fun showAndHide(
        showFm: Fragment,
        args: Bundle?,
        showFmTag: String?,
        hideFm: Fragment?,
        fmTransactionAnim: IFmTransactionAnim?
    ) {
        FmTransitionsUtil.showAndHide(
            fmManager = supportFragmentManager,
            containerViewId = getFragmentContainerId(),
            showFm = showFm,
            showFmTag = showFmTag,
            hideFm = hideFm,
            fmTransactionAnim = fmTransactionAnim ?: getDefaultFmTransactionAnim()
        )
    }

    override fun getDefaultFmTransactionAnim(): IFmTransactionAnim {
        return DefaultFmTransactionAnim()
    }


    // fragment 操作 end
}